package org.papillion39.sechelper.business.model;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.List;

/**
 * A user in the sechelper system. The ID property is read-only. The password
 * property is only set if the password is desired to be changed.
 * @author Jonathan Paz <jonathan.paz@ottr.com>
 */
public class User implements Serializable {
    private int id;
    private String username;
    private char[] password;
    private String[] role;
    private final PropertyChangeSupport support = new PropertyChangeSupport(this);

    /**
     * Creates a new blank user
     */
    public User() {
    }

    /**
     * Creates a new user object with the given user name and roles
     * @param id
     * @param username the username for the user
     * @param roles the list of roles associated to the user
     */
    public User(int id, String username, List<String> roles) {
        this.id = id;
        this.username = username;
        if (roles != null && !roles.isEmpty()) {
            this.role = roles.toArray(new String[roles.size()]);
        }
    }

    /**
     * Creates a new user object with the given user name and roles
     * @param id
     * @param username the username for the user
     * @param roles the list of roles associated to the user
     */
    public User(int id, String username, String... roles) {
        this.id = id;
        this.username = username;
        if (roles != null && roles.length > 0) {
            this.role = roles;
        }
    }

    /**
     * Gets the user id
     * @return the user id
     */
    public int getId() {
        return id;
    }

    /**
     * Gets the username
     * @return the username
     */
    public String getUsername() {
        return username;
    }

    /**
     * Sets the username
     * @param username the username
     */
    public void setUsername(String username) {
        String oldusername = this.username;
        this.username = username;
        support.firePropertyChange("username", oldusername, username);
    }

    /**
     * Retrieves the list of roles associated with this user. This is a copy of
     * the list; any changes made to the returned list will not affect this object.
     * To make any changes to the roles, use the {@link #addRole(java.lang.String)}
     * {@link #removeRole(java.lang.String)}, {@link #setRoles(java.util.List)},
     * or {@link #clearRoles() methods.
     * @return a copy of this user's roles
     */
    public String[] getRole() {
        return role;
    }

    /**
     * Sets the list of roles for this user. This method replaces this object's
     * list of roles with the items from the given list. Any changes made to the
     * given list will not be reflected by this object's list of roles.
     * @param roles a new list of roles
     */
    public void setRole(String[] role) {
        String[] oldrole = this.role;
        this.role = role;
        support.firePropertyChange("role", oldrole, role);
    }

    public String getRole(int index) {
        return role[index];
    }

    public void setRole(int index, String role) {
        String oldrole = this.role[index];
        this.role[index] = role;
        support.fireIndexedPropertyChange("role", index, oldrole, role);
    }

    public char[] getPassword() {
        return password;
    }

    public void setPassword(char[] password) {
        this.password = password;
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        support.addPropertyChangeListener(listener);
    }

    public void removePropertyChangeListener(PropertyChangeListener listener) {
        support.removePropertyChangeListener(listener);
    }

    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
        support.addPropertyChangeListener(propertyName, listener);
    }

    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
        support.removePropertyChangeListener(propertyName, listener);
    }
}
